﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Windows.ApplicationModel.Resources;
using Windows.Storage.Pickers;
using Windows.Storage;
using Windows.System.UserProfile;
using Windows.UI.Popups;

using SeriesManager.Model;
using SeriesManager.Model.Banner;
using Windows.UI.Xaml.Data;
using System.Runtime.Serialization;
using Windows.UI.Xaml.Controls;
using System.Threading.Tasks;
using WinRTFramework.Common;
using WinRTFramework.Interfaces.Dialog.ViewModel;
using WinRTFramework.Interfaces.AppStates;

namespace SeriesManager.ViewModel
{
    public class MediaDetailViewModel : ViewModelBase, IRequireDialogService, ISupportTransientState
    {
        #region Properties

        private SeriesModel seriesModel;
        private bool loading;

        public ICollectionView View
        {
            get;
            private set;
        }

        public bool Loading
        {
            get 
            { 
                return this.loading; 
            }
            private set 
            {
                base.SetProperty<bool>(ref this.loading, value);
            }
        }

        #endregion

        #region DelegateCommands

        public DelegateCommand<ItemClickEventArgs> LockScreenCommand
        {
            get;
            private set;
        }

        public DelegateCommand<ItemClickEventArgs> OKCommand
        {
            get;
            private set;
        }

        public DelegateCommand<ItemClickEventArgs> SavePictureCommand
        {
            get;
            private set;
        }

        #endregion

        public MediaDetailViewModel()
        {
            this.LockScreenCommand = new DelegateCommand<ItemClickEventArgs>(OnLockscreenExecuted, OnLockscreenCanExecute);
            this.OKCommand = new DelegateCommand<ItemClickEventArgs>(OnOKExecuted, OnOKCanExecute);
            this.SavePictureCommand = new DelegateCommand<ItemClickEventArgs>(OnSavePictureExecuted, OnSavePictureCanExecute);
        }

        #region DelegateCommandImplementation

        private async void OnSavePictureExecuted(ItemClickEventArgs e)
        {
            if (this.View != null && this.View.CurrentItem != null)
            {
                var currentItem = this.View.CurrentItem as FanArtBannerModel;

                StorageFile source;
                try
                {
                    source = await StorageFile.GetFileFromApplicationUriAsync(new Uri(currentItem.LocalPath));
                }
                catch (FileNotFoundException) { return; }

                FileSavePicker savePicker = new FileSavePicker();
                savePicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
                savePicker.FileTypeChoices.Add("JPG/JPEG", new string[] { ".jpg" });
                savePicker.SuggestedFileName = this.seriesModel.Name;
                StorageFile file = await savePicker.PickSaveFileAsync();

                if (file != null)
                {
                    await source.CopyAndReplaceAsync(file);
                }
            }
        }

        private bool OnSavePictureCanExecute(ItemClickEventArgs e)
        {
            return this.View != null && this.View.CurrentItem != null && !this.loading;
        }

        private async void OnLockscreenExecuted(ItemClickEventArgs e)
        {
            if (this.View != null && this.View.CurrentItem != null)
            {
                var currentItem = this.View.CurrentItem as FanArtBannerModel;
                var res = new ResourceLoader();

                try
                {
                    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri(currentItem.LocalPath));
                    await LockScreen.SetImageFileAsync(file);
                }
                catch 
                {
                    ShowFailedMessage(res);
                    return;
                }
                await this.DialogService.ShowAsync(res.GetString("LockscreenMessage"), res.GetString("LockscreenTitle"));
            }
        }

        private async void ShowFailedMessage(ResourceLoader res)
        {
            await this.DialogService.ShowAsync(res.GetString("LockscreenFailedMessage"), res.GetString("LockscreenFailedTitle"));
        }

        private bool OnLockscreenCanExecute(ItemClickEventArgs e)
        {
            return this.View != null && this.View.CurrentItem != null && !this.loading;
        }

        private void OnOKExecuted(ItemClickEventArgs e)
        {
            this.seriesModel.FanArt = (FanArtBannerModel)this.View.CurrentItem;
            base.NavigationService.GoBackCommand.Execute(null);
        }

        private bool OnOKCanExecute(ItemClickEventArgs e)
        {
            return this.seriesModel != null && this.seriesModel.Subscription && this.View != null && this.View.CurrentItem != null && !this.loading;
        }

        #endregion

        private void CurrentItem_Changing(object sender, CurrentChangingEventArgs e)
        {
            if (this.View != null && this.View.CurrentItem != null)
            {
                var currentItem = this.View.CurrentItem as FanArtBannerModel;
                currentItem.PropertyChanged -= currentItem_PropertyChanged;
            }
        }

        private void CurrentItem_Changed(object sender, object e)
        {
            this.OKCommand.NotifyCanExecuteChanged();
            this.LockScreenCommand.NotifyCanExecuteChanged();
            this.SavePictureCommand.NotifyCanExecuteChanged();

            if (this.View != null && this.View.CurrentItem != null)
            {
                var currentItem = this.View.CurrentItem as FanArtBannerModel;
                this.Loading = currentItem.Loading;
                currentItem.PropertyChanged += currentItem_PropertyChanged;
            }
        }

        private void currentItem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Loading")
            {
                if (this.View != null && this.View.CurrentItem != null)
                {
                    var currentItem = this.View.CurrentItem as FanArtBannerModel;
                    this.Loading = currentItem.Loading;
                }

                this.OKCommand.NotifyCanExecuteChanged();
                this.LockScreenCommand.NotifyCanExecuteChanged();
                this.SavePictureCommand.NotifyCanExecuteChanged();
            }
        }

        public override void OnNavigatedTo(object navigationParameter)
        {
            this.View = new CollectionViewSource() { Source = AppX.Instance.Current.FanArtBanners }.View;
            this.View.CurrentChanged += CurrentItem_Changed;
            this.View.CurrentChanging += CurrentItem_Changing;
            base.OnPropertyChanged<ICollectionView>(() => this.View);

            this.seriesModel = AppX.Instance.Current;
            this.UpdateTransientState(navigationParameter);
        }

        public WinRTFramework.Interfaces.Dialog.IDialogService DialogService
        {
            set;
            private get;
        }

        public void UpdateTransientState(object state)
        {
            var item = this.View.FirstOrDefault(B => (B as FanArtBannerModel).ID == (int)state);
            if (item != null)
            {
                this.View.MoveCurrentTo(item);
            }
        }

        public object GetTransientState()
        {
            if (this.View != null && this.View.CurrentItem != null)
            {
                return (this.View.CurrentItem as FanArtBannerModel).ID;
            }
            return null;
        }

        public IEnumerable<Type> GetTransientStateTypes()
        {
            yield return typeof(int);
        }
    }
}